home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / tools / zmc3v078 / zmc3v078.lzh / SRCSV078.LZH / V3MACRO.C < prev    next >
C/C++ Source or Header  |  2000-06-01  |  19KB  |  721 lines

  1. /* ==========================
  2.      V3マクロ展開
  3.      ここだけ当面日本語注釈
  4.      高速化は後回し アルゴリズム低級
  5.  
  6.      .include もここで処理する
  7.    ========================== */
  8. /*#define DEBUG*/
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <ctype.h>
  14. #include "parsesub.h"
  15. #include "etc.h"
  16. #include "68lib.h"
  17. #include "switch.h"
  18. #include "structs2.h"
  19. #ifndef NOINCLUDE
  20.     #include "readfile.h"
  21. #endif
  22.  
  23. UBYTE *expandV3macro(UBYTE *zms, LINEDATA *ld, LINEFILEDATA *lfd);
  24.  
  25.  
  26.  
  27. /* 行毎にデータを分割するための構造 */
  28. typedef struct zmsData {
  29.     struct zmsData *next;
  30.     UBYTE  *linebuf;        /*  */
  31.     DWORD  line;            /* 行番号 */
  32. } ZMSDATA;
  33.  
  34.  
  35. typedef struct v3macropara {
  36.     struct    v3macropara *next;
  37.     char *para;
  38. } V3MACROPARA;
  39.  
  40. /* マクロ記憶 */
  41. typedef struct v3macro {
  42.     struct v3macro *next;
  43.     UBYTE *state1;            /* 展開前 */
  44.     UBYTE *state2;            /* 展開後 */
  45.     DWORD paras;            /* パラメータの数 */
  46. /*    struct v3macropara *para; */
  47. } V3MACRO;
  48.  
  49. V3MACRO *expandMacroMain(ZMSDATA *zmsdata, LINEDATA *ld, LINEFILEDATA *lfd);
  50. ZMSDATA *defineMacroMain(ZMSDATA *zmsdata, char **lbuf__, V3MACRO *mbuf, LINEDATA *ld);
  51. void replaceMacro(ZMSDATA *zmsdata, V3MACRO *mbuf);
  52.  
  53. ZMSDATA *makeLineBuf(UBYTE *zmsbuf, LINEDATA *ld, LINEFILEDATA *lfd);
  54. UBYTE *restoreLineBuf(ZMSDATA *zmsdata);
  55. char *skipSpc2(char *lbuf);
  56. char *skipSpc3(char *lbuf, ZMSDATA **zmsdata);
  57. UBYTE *getpara2(UBYTE *lbuf, char **para);
  58. #ifndef    NOINCLUDE
  59.     void includeFile(ZMSDATA *zmsdata, char *filename, LINEDATA *ld, LINEFILEDATA *lfd);
  60. #endif
  61.  
  62.  
  63.  
  64. void freeV3macro(V3MACRO *macro) {
  65.     while (macro->next != NULL) {
  66.         V3MACRO *before = macro;
  67.         efree(macro->state1,"mbuf->state1");
  68.         efree(macro->state2,"mbuf->state2");
  69.         macro = macro->next;
  70.         efree(before,"before");
  71.     }
  72.     efree(macro,"macro"); 
  73. }
  74.  
  75.  
  76.  
  77. #ifndef NOINCLUDE
  78. void includeFile(ZMSDATA *zmsdata, char *filename, LINEDATA *ld, LINEFILEDATA *lfd)
  79. {
  80.     ZMSDATA *zmsdata2;
  81.     ZMSDATA *orgnext = zmsdata->next;
  82.     ZMSDATA *z;
  83.     UBYTE *buf;
  84.     const char *inpEXT[] = { ".zmc", NULL};
  85.     LINEDATA *addld, *bakld, *l;
  86.  
  87.     buf = readFile1(filename, strlen(filename), inpEXT, 0);
  88.  
  89.     lfd->next = (LINEFILEDATA*)emalloc(sizeof(LINEFILEDATA) * 1,"linefile_in_includeFile");
  90.     lfd = lfd->next;
  91.     lfd->next = NULL;
  92.     lfd->filename = (char*)emalloc(sizeof(char) * (strlen(filename) + 1), "filename_in_includeFile");
  93.     strcpy(lfd->filename, filename);
  94.  
  95.     addld = (LINEDATA*)emalloc(sizeof(LINEDATA) * 1,"line_in_includeFile");
  96.  
  97.     zmsdata2 = makeLineBuf(buf, addld, lfd);
  98.     efree(buf,"buf_in_includeFile");
  99.  
  100.     zmsdata->next = zmsdata2;
  101.     z = zmsdata2;
  102.     while (zmsdata2->next) {
  103.         z = zmsdata2;
  104.         zmsdata2 = zmsdata2->next;
  105.     }
  106.     z->next = orgnext;
  107.     efree(zmsdata2,"zmsdata2");    /* add v0.70 */
  108.  
  109.     bakld = ld->next;
  110.     l = addld;
  111.     ld->next = addld;
  112.     while (ld->next) {
  113.         l = ld;
  114.         ld = ld->next;
  115.     }
  116.     l->next = bakld;
  117.     efree(ld,"l");
  118. }
  119. #endif    /* #ifndef NOINCLUDE */
  120.  
  121.  
  122.  
  123.  
  124.  
  125. UBYTE *expandV3macro(UBYTE *zms, LINEDATA *ld, LINEFILEDATA *lfd)
  126. {
  127.     ZMSDATA *zmsdata;
  128.     UBYTE *zmsbuf;
  129. /*int i;*/
  130.  
  131.     zmsdata = makeLineBuf(zms,ld, lfd);        /* まず行毎にデータ分割 */
  132. /*
  133. for (i = 1; i < 3; i++) {
  134.     ld->next = (LINEDATA*)emalloc(sizeof(LINEDATA) * 1,"linedata_next_in_makeLineBuf");
  135.     ld->next->line = ld->line;
  136.     ld = ld->next;
  137.     ld->next = NULL;
  138. }
  139. */
  140.     freeV3macro(expandMacroMain(zmsdata,ld,lfd));
  141.     efree(zms,"zms_in_v3macro");                        /* もう不要 */
  142.  
  143. #ifdef AA
  144.     /* 表示テスト */
  145. fprintf(stderr,"=============================\n");
  146.     zmsdata2 = zmsdata;
  147.     while (zmsdata2->next) {
  148.         ZMSDATA *before = zmsdata2;
  149.         UBYTE *buf = zmsdata2->linebuf;
  150.         fprintf(stderr,"%s",zmsdata2->linebuf);
  151.         zmsdata2 = zmsdata2->next;
  152. /*
  153.         efree(buf);
  154.         efree(before);
  155. */
  156.     }
  157. #endif
  158.  
  159.     zmsbuf = restoreLineBuf(zmsdata);
  160.  
  161.     return zmsbuf;
  162. }
  163.  
  164.  
  165.  
  166. /* ============================================
  167.      テキストをスキャンし、もしマクロがあれば
  168.      定義する
  169.    ============================================ */
  170. V3MACRO *expandMacroMain(ZMSDATA *zmsdata, LINEDATA *ld, LINEFILEDATA *lfd)
  171. {
  172.     V3MACRO *mbuf;
  173.     int defMacroFlag = 1;
  174.  
  175.     mbuf = (V3MACRO*)emalloc(sizeof(V3MACRO) * 1,"mbuf_in_expandMacroMain");
  176.     mbuf->next = NULL;
  177.  
  178.     while (zmsdata->next != NULL) {
  179.         char *lbuf;
  180.  
  181.         replaceMacro(zmsdata, mbuf);
  182.  
  183.         lbuf = skipSpc2(zmsdata->linebuf);
  184.         if (*lbuf == '.') {
  185.             if (!stricmp2(lbuf, ".define")) {    /* マクロ定義が存在 */
  186.                 /* if (defMacroFlag) { */
  187.                     zmsdata = defineMacroMain(zmsdata, &lbuf, mbuf, ld);
  188.                 /* } */
  189.                 if (!defMacroFlag) {    /* 手抜き:仮対策 */
  190.                     strcpy(zmsdata->linebuf, "\n");        /* erase define line */
  191.                 }
  192. #ifndef NOINCLUDE
  193.             } else if (!stricmp2(lbuf,".include")) {
  194.                 char filename[1024];
  195.                 int p = 0;
  196.  
  197.                 lbuf = skipSpc2(lbuf + 8);
  198.                 while (isgraph(*lbuf) && *lbuf != '/') {
  199.                     filename[p++] = *lbuf++;
  200.                 }
  201.                 filename[p] = '\0';
  202.                 includeFile(zmsdata, filename, ld, lfd);
  203. #endif    /* #ifndef NOINCLUDE */
  204.             } else if(!stricmp2(lbuf, ".track")) {
  205.                 defMacroFlag = 0;
  206.             }
  207.         } else if (*lbuf == '(') {
  208.             lbuf = skipSpc2(lbuf);
  209.             if (*lbuf == 't' || *lbuf == 'T') {    /* (t..) 開始(共通トラック部終了) */
  210.                 defMacroFlag = 0;
  211.                 /* break; */                    /* マクロスキャン打ち切り */
  212.             }
  213.         }
  214.         zmsdata = zmsdata->next;
  215.         ld = ld->next;
  216.     }
  217.  
  218.     return mbuf;
  219. }
  220.  
  221.  
  222.  
  223. /* ベタのデータを行毎に分ける */
  224. ZMSDATA *makeLineBuf(UBYTE *zms, LINEDATA *ld, LINEFILEDATA *lfd)
  225. {
  226.     ZMSDATA *zmsdata, *ret;
  227.     DWORD line = 1;
  228.  
  229.     ret = zmsdata = (ZMSDATA*)emalloc(sizeof(ZMSDATA) * 1,"zmsdata_in_makeLineBuf");
  230.     zmsdata->next = NULL;
  231.     zms--;
  232.  
  233.     while (*++zms != 0xFF) {
  234.         UBYTE *before = zms;
  235.         /* 1 line scan */
  236.         while (*zms != 0x0A && *zms != 0xFF) {
  237.             zms++;
  238.         }
  239.         /* copy line */
  240.         zmsdata->linebuf = (UBYTE*)emalloc(sizeof(UBYTE) * (zms - before + 2),"linebuf_in_makeLineBuf");
  241.         strncpy(zmsdata->linebuf, before, zms - before + 1);
  242.         zmsdata->linebuf[zms - before + 1] = '\0';
  243.         zmsdata->line = line;
  244.         ld->line = line++;
  245.         ld->filename = lfd->filename;
  246.  
  247.         /* malloc next list */
  248.         zmsdata->next = (ZMSDATA*)emalloc(sizeof(ZMSDATA) * 1,"next_in_makeLineBuf");
  249.         zmsdata = zmsdata->next;
  250.         zmsdata->next = NULL;
  251.  
  252.         ld->next = (LINEDATA*)emalloc(sizeof(LINEDATA) * 1,"linedata_next_in_makeLineBuf");
  253.         ld = ld->next;
  254.         ld->next = NULL;
  255.     }
  256.     return ret;
  257. }
  258.  
  259. #ifndef MSDOS
  260.     #define ZMSBUF_SIZE            (128 * 1024)
  261.     #define ZMSBUF_EXPANDSIZE    (64 * 1024)
  262. #else
  263.     #define ZMSBUF_SIZE            (16 * 1024)
  264.     #define ZMSBUF_EXPANDSIZE    (4 * 1024)
  265. #endif
  266.  
  267. /* 行単位のデータを元のベタデータに戻す */
  268. UBYTE *restoreLineBuf(ZMSDATA *zmsdata)
  269. {
  270.     UBYTE *zmsbuf2, *zpos;
  271.     DWORD zmssize = ZMSBUF_SIZE;
  272. #ifdef AA
  273. fprintf(stderr,"----------------\n");
  274. #endif
  275.     zpos = zmsbuf2 = (UBYTE*)emalloc(sizeof(UBYTE) * zmssize,"zmsbuf2");
  276.     while (zmsdata->next != NULL) {                        /* 元のベタデータとして連結 */
  277.         ZMSDATA *before = zmsdata;
  278.         DWORD len;
  279.         len = strlen(zmsdata->linebuf);
  280.         /*  ここで拡張すればメモリリークの心配はないはず */
  281.         if (len + 1 + (zpos - zmsbuf2) > zmssize) {
  282.             /* メモリ拡張のオーバーヘッド回避のため多めに確保 */
  283.             DWORD p = zpos - zmsbuf2;
  284.             zmssize += len + 1 + ZMSBUF_EXPANDSIZE;
  285.             zmsbuf2 = (UBYTE*)erealloc(zmsbuf2, zmssize,"zmsbuf2_1");
  286.             zpos = zmsbuf2 + p;
  287.         }
  288.         strcpy(zpos, zmsdata->linebuf);
  289.         zpos += len;
  290.         zmsdata = zmsdata->next;
  291.         efree(before->linebuf,"before->linebuf");
  292.         efree(before,"before");
  293.     }
  294.     efree(zmsdata,"zmsdata");
  295.     *zpos++ = '\xFF';
  296.     *zpos++ = '\xFF';
  297.     *zpos++ = '\xFF';
  298.     *zpos++ = '\xFF';
  299.     *zpos++ = '\xFF';
  300.     *zpos++ = '\xFF';
  301.  
  302.     zmsbuf2 = erealloc(zmsbuf2, zpos - zmsbuf2 + 1,"zmsbuf2_2");
  303.     if (getSwitchVal('d') != RES_VAL) {
  304.         FILE *fp = fopen("debug.zms","wb");
  305.         if (fp == (FILE*)NULL) {
  306.             fatal(1,"can't open debug.zms.\n");
  307.         }
  308.         fwrite(zmsbuf2,sizeof(UBYTE),zpos-zmsbuf2+1 - 7,fp);
  309.         fclose(fp);
  310.     }
  311.     return zmsbuf2;
  312. }
  313.  
  314. char *skipSpc2(char *lbuf)
  315. {
  316.     while ((*lbuf == ' ' || *lbuf == '\t') && *lbuf) {
  317.         lbuf++;
  318.     }
  319.     if (*lbuf == '/' ) {
  320.         while (*lbuf != 0x0A) {
  321.             lbuf++;
  322.         }
  323.     }
  324.     return lbuf;
  325. }
  326.  
  327. char *skipSpc3(char *lbuf, ZMSDATA **zmsdata)
  328. {
  329.     int f;
  330.  
  331.     do {
  332.         f = 0;
  333.         while (*lbuf && (*lbuf == ' ' || *lbuf == '\t')) {
  334.             lbuf++;
  335.         }
  336.         if (*lbuf == '/' ) {
  337.             while (*lbuf) {
  338.                 lbuf++;
  339.             }
  340.         }
  341.         if (!*lbuf) {
  342.             *zmsdata = (*zmsdata)->next;
  343.             lbuf = (*zmsdata)->linebuf;
  344.             if ((*zmsdata)->next) {
  345.                 f = 1;
  346.             } else {
  347.                 zmserror("macro definition is not closed.",(*zmsdata)->line,(*zmsdata)->linebuf,lbuf,0,1);
  348.             }
  349.         }
  350.     } while (f);
  351.     return lbuf;
  352. }
  353.  
  354.  
  355.  
  356. /* ====================
  357.      マクロ定義メイン
  358.    ==================== */
  359.  
  360. ZMSDATA *defineMacroMain(ZMSDATA *zmsdata, char **lbuf__, V3MACRO *mbuf, LINEDATA *ld)
  361. {
  362.     char *lbuf = *lbuf__ + 7, *lbuf_;
  363.     ZMSDATA *zmsdata_ = zmsdata;
  364.     int len, paras = 0, paras2 = 0, pmode = -1;
  365.     DWORD slensize = 128, slen = 0;
  366.     V3MACRO *mbuftemp;
  367.     int bnest;
  368.  
  369.     /* マクロ定義文字列抽出 */
  370.     lbuf = skipSpc2(lbuf);
  371.     lbuf_ = lbuf;
  372.     while (*lbuf != ' ' && *lbuf != '\t') {        /* エラー処理いい加減 */
  373.         lbuf++;
  374.     }
  375.     len = lbuf - lbuf_;
  376.  
  377.  
  378.     /* マクロ定義リスト末尾に移動 */
  379.     while (mbuf->next != NULL) {
  380.         int mlen = strlen(mbuf->state1);
  381.  
  382.         if (mlen == len) {
  383.             if(!stricmp2(mbuf->state1, lbuf_)) {
  384.                 zmserror("same macro name is already used.",zmsdata->line,zmsdata->linebuf,lbuf,0,1);
  385.             }
  386.             break;
  387.         } else if (mlen < len) {
  388.             break;
  389.         }
  390.         mbuf = mbuf->next;
  391.     }
  392.  
  393.     /* マクロ名定義 */
  394.     mbuftemp = (V3MACRO*)emalloc(sizeof(V3MACRO) * 1,"mbuftemp");
  395.     mbuftemp->state1 = (char*)emalloc(sizeof(char) * (len + 1),"mbuftemp->state1");
  396.     strncpy(mbuftemp->state1, lbuf_, len);
  397.     (mbuftemp->state1)[len] = '\0';
  398.     strlwr(mbuftemp->state1);
  399.  
  400.     if (mbuf->next == NULL) {        /* リスト最後尾追加 */
  401.         /* リスト最前列である可能性があるためすげ替えでなくコピーにしている */
  402.         mbuf->state1 = mbuftemp->state1;
  403.         efree(mbuftemp,"mbuftemp");
  404.  
  405.         mbuf->next = (V3MACRO*)emalloc(sizeof(V3MACRO) * 1,"mbuf->next");
  406.         mbuf->next->next = NULL;
  407.     } else {                        /* リスト途中に挿入 */
  408.         UBYTE *state1 = mbuftemp->state1;
  409.  
  410.         mbuftemp->state1 = mbuf->state1;
  411.         mbuftemp->state2 = mbuf->state2;
  412.         mbuftemp->paras = mbuf->paras;
  413.         mbuftemp->next = mbuf->next;
  414.         mbuf->next = mbuftemp;
  415.         mbuf->state1 = state1;
  416.     }
  417.  
  418.  
  419.     /* パラメータ記述法チェック % or %n */
  420.     lbuf = skipSpc2(lbuf);
  421.     while (*lbuf != '{') {
  422.         if (*lbuf++ == '%') {
  423.             lbuf = skipSpc3(lbuf, &zmsdata);
  424.             if (isdigit(*lbuf)) {        /* %n pmode==1 */
  425.                 if (!paras) {            /* はじめの1個 */
  426.                     pmode = 1;
  427.                 } else if (!pmode) {    /* % %n */
  428.                     zmserror("macro parameter definition error.",zmsdata->line,zmsdata->linebuf,lbuf,0,1);
  429.                 }
  430.                 while (isdigit(*lbuf)) {    /* 二桁以上の数字をスキップ */
  431.                     lbuf++;
  432.                 }
  433.             } else {
  434.                 if (!paras) {            /* はじめの1個 */
  435.                     pmode = 0;
  436.                 } else if (pmode) {        /* %n % */
  437.                     zmserror("macro parameter definition error.",zmsdata->line,zmsdata->linebuf,lbuf,0,1);
  438.                 }
  439.             }
  440.             lbuf = skipSpc3(lbuf, &zmsdata);
  441.             if (*lbuf == ',') {
  442.                 lbuf++;
  443.             }
  444.             paras++;
  445.         } else {                        /* それ以外はエラー */
  446.             zmserror("macro parameter definition error.",zmsdata->line,zmsdata->linebuf,lbuf,0,1);
  447.         }
  448.         lbuf = skipSpc2(lbuf);
  449.     }
  450.     mbuf->paras = paras;
  451.  
  452.     /* コンテンツ記述開始チェック */
  453.     if (*lbuf != '{') {
  454.         zmserror("macro parameter definition error.",zmsdata->line,zmsdata->linebuf,lbuf,0,1);
  455.     }
  456.     lbuf = skipSpc3(lbuf, &zmsdata);
  457.     lbuf_ = lbuf;
  458.  
  459.  
  460.     /* コンテンツ記述チェック */
  461.     while (*lbuf != '}') {
  462.         if (*lbuf == 0x0d || *lbuf == 0x0a || !*lbuf) {
  463.             zmsdata = zmsdata->next;
  464.             ld = ld->next;
  465.             lbuf = zmsdata->linebuf;
  466.             if (zmsdata->next == NULL) {
  467.                 zmserror("macro definition is not closed.",zmsdata->line,zmsdata->linebuf,lbuf,0,1);
  468.             }
  469.             continue;
  470.         }
  471.         if (*lbuf == '%') {
  472.             DWORD p;
  473.             int err;
  474.  
  475.             lbuf = skipSpc3(lbuf + 1, &zmsdata);
  476.             lbuf = getnum2(lbuf, &p, &err);
  477.             if (err) {            /* % */
  478.                 if (pmode > 0) {
  479.                     zmserror("macro contents mismatches(% and %n).",zmsdata->line,zmsdata->linebuf,lbuf,0,1);
  480.                 }
  481.             } else {            /* %n */
  482.                 if (!pmode) {
  483.                     zmserror("macro contents mismatches(% and %n).",zmsdata->line,zmsdata->linebuf,lbuf,0,1);
  484.                 }
  485.                 if (p > paras && paras) {
  486.                     zmserror("too large the parameter# is.",zmsdata->line,zmsdata->linebuf,lbuf,0,1);
  487.                 }
  488.             }
  489.             paras2++;
  490.             if (!pmode && paras2 > paras && paras) {
  491.                 zmserror("too many parameters in macro contents.",zmsdata->line,zmsdata->linebuf,lbuf,0,1);
  492.             }
  493.         } else {
  494.             lbuf++;
  495.         }
  496.     }
  497.     if (!paras && paras2) {
  498.         mbuf->paras = paras2;
  499.     }
  500.  
  501.     /* コンテンツのコピー */
  502.     lbuf = lbuf_ + 1;        /* skip '{' */
  503.     zmsdata = zmsdata_;
  504.     mbuf->state2 = (UBYTE*)emalloc(sizeof(UBYTE) * slensize,"mbuf->state2");
  505.     bnest = 1;
  506.     while (bnest > 0) {
  507.         if (*lbuf == '{') {                /* {..} nest check */
  508.             bnest++;
  509.         } else if (*lbuf == '}') {
  510.             if (--bnest <= 0) {
  511.                 lbuf++;
  512.                 break;
  513.             }
  514.         }
  515.         if (*lbuf == 0x0d || *lbuf == 0x0a || *lbuf == '/' || !*lbuf) {
  516.             zmsdata = zmsdata->next;
  517.             ld = ld->next;
  518.             lbuf = zmsdata->linebuf;
  519.             if (zmsdata->next == NULL) {
  520.                 zmserror("macro definition is not closed.",zmsdata->line,zmsdata->linebuf,lbuf,0,1);
  521.             }
  522.             continue;
  523.         }
  524.         mbuf->state2[slen++] = *lbuf++;
  525.         if (slen >= slensize - 16) {
  526.             slensize += 128;
  527.             mbuf->state2 = (UBYTE*)erealloc(mbuf->state2, sizeof(UBYTE) * slensize,"mbuf->state2");
  528.         }
  529.     }
  530.     mbuf->state2[slen] = '\0';
  531. /*
  532. fprintf(stderr,"Defined: %s %d %s",mbuf->state1, mbuf->paras, mbuf->state2);
  533. fprintf(stderr,"(%d)\n",strlen(mbuf->state2));
  534. */
  535.  
  536.     *lbuf__ = lbuf;
  537.  
  538.     return zmsdata;
  539. }
  540.  
  541.  
  542. /* マクロが使われていれば置換する */
  543. /* まだBM法などのアルゴリズムは使っておらず、単純なもの */
  544. void replaceMacro(ZMSDATA *zmsdata, V3MACRO *mbuf)
  545. {
  546.     while (mbuf->next != NULL) {
  547.         char *lbuf = zmsdata->linebuf;
  548.  
  549.         lbuf = skipSpc2(lbuf);        /* .defineの定義名はマクロ展開しない */
  550.         if (!stricmp2(lbuf, ".define")) {
  551.             lbuf += 7;    /* strlen(".define"); */
  552.             lbuf = skipSpc2(lbuf);
  553.             while (*lbuf != ' ' && *lbuf != '\t' && *lbuf != 0x0A && *lbuf) {
  554.                 lbuf++;
  555.             }
  556.         }
  557.  
  558.         while (*lbuf) {
  559.             if (*lbuf == '/') {
  560.                 break;            /* 注釈内はマクロ展開しない */
  561.             } else if (!stricmp2(lbuf,mbuf->state1)) {
  562.                 char *lbuf_ = lbuf;
  563.                 int i;
  564.                 UBYTE *pbuf;
  565.                 DWORD pbuflen = 0, pbuflenmax = 128;
  566.                 V3MACROPARA *mpara, *mpara_;
  567.                 char *state2 = mbuf->state2;
  568.  
  569.                 mpara_ = mpara = (V3MACROPARA*)emalloc(sizeof(V3MACROPARA) * 1,"mpara");
  570.                 mpara->para = NULL;
  571.                 mpara->next = NULL;
  572. /*
  573. fprintf(stderr,"macro is used! %s / %s / %s\n",mbuf->state1,lbuf,mbuf->state2);
  574. */
  575.                 lbuf += strlen(mbuf->state1);
  576.  
  577.                 /* 展開パラメータ取得 */
  578.                 for (i = 0; i < mbuf->paras; i++) {
  579.                     lbuf = getpara2(lbuf,&(mpara->para));
  580. /*
  581. fprintf(stderr,"p: %s(%d) ",mpara->para,strlen(mpara->para));
  582. */
  583.                     if (*lbuf == ',') {
  584.                         lbuf++;
  585.                     } else {
  586.                         break;
  587.                     }
  588.                     mpara->next = (V3MACROPARA*)emalloc(sizeof(V3MACROPARA) * 1,"mpara->next");
  589.                     mpara = mpara->next;
  590.                     mpara->para = NULL;
  591.                     mpara->next = NULL;
  592.                 }
  593.                 mpara = mpara_;
  594. /*
  595. fprintf(stderr,"![%s]",state2);
  596. */
  597.                 /* 展開後MMLの作成 */
  598.                 pbuf = (UBYTE*)emalloc(sizeof(UBYTE) * pbuflenmax,"pbuf");
  599.                 while (*state2) {
  600.                     if (*state2 != '%') {        /* マクロパラメータでない場合 */
  601.                                                         /* そのまま1文字コピー */
  602. /*
  603. fprintf(stderr,".");
  604. */
  605.                         pbuf[pbuflen++] = *state2++;
  606.                         if (pbuflen > pbuflenmax - 16) {
  607.                             pbuflenmax += 128;
  608.                             pbuf = (UBYTE*)erealloc(pbuf, sizeof(UBYTE) * pbuflenmax,"pbuf");
  609.                         }
  610.                     } else {                            /* マクロパラメータなら */
  611.                                                         /* 対応するパラメータを埋める */
  612.                         int err;
  613.                         DWORD pno;
  614. /*
  615. fprintf(stderr,"%");
  616. */
  617.                         state2 = getnum2(state2 + 1, &pno, &err);
  618.                         if (!err) {                        /* 数字付パラメータなら */
  619.                             int i;
  620.  
  621.                             mpara = mpara_;
  622.                             for (i = 1; i < pno; i++) {
  623.                                 if (mpara->next) {
  624.                                     mpara = mpara->next;
  625.                                 } else {
  626.                                     break;
  627.                                 }
  628.                             }
  629.                         }
  630.                         if (mpara->para != NULL) {
  631.                             if (pbuflen + (DWORD)strlen(mpara->para) > pbuflenmax - 16) {
  632.                                 pbuflenmax += strlen(mpara->para) + 128;
  633.                                 pbuf = (UBYTE*)erealloc(pbuf, sizeof(UBYTE) * pbuflenmax,"pbuf");
  634.                             }
  635. /*
  636. fprintf(stderr,"B[%s]",mpara->para);
  637. */
  638.                             strcpy(&pbuf[pbuflen],mpara->para);
  639.                             pbuflen += strlen(mpara->para);
  640.                             pbuf[pbuflen] = '\0';
  641.                         }
  642. /*
  643. fprintf(stderr,"C[%s](%d)",pbuf,strlen(mpara->para));
  644. */
  645.  
  646.                         mpara = mpara->next;
  647.                     }
  648.                 }
  649.                 pbuf[pbuflen] = '\0';
  650.  
  651.  
  652. /*
  653. fprintf(stderr,"置換:%s\n",pbuf);
  654. fprintf(stderr,"置換前:%s\n",zmsdata->linebuf);
  655. */
  656.                 /* パラメータ領域の開放 */
  657.                 do {
  658.                     mpara = mpara_;
  659.                     mpara_ = mpara_->next;
  660.                     if (mpara->para != NULL) efree(mpara->para,"mbuf->para");
  661.                     efree(mpara,"mpara");
  662.                 } while (mpara_ != NULL);
  663.  
  664.                 /* 展開済みMMLを元のMMLと置換する */
  665.                 /* lbuf, lbuf_, pbuf[plen], zmsdata->linebuf */
  666.                 /* 転送バイト数: strlen(zmsdata->linebuf) - (lbuf - zmsdata->linebuf) */
  667.                 /* 転送from: lbuf */
  668.                 /* 転送to:   lbuf + (pbuflen - (lbuf - lbuf_)) */
  669.                 /* reallocするためポインタでなくオフセットを用いる */
  670.                 {
  671.                     DWORD transbytes = strlen(zmsdata->linebuf) - ((UBYTE*)lbuf - zmsdata->linebuf) + 1;    /* +1: for \0 */
  672.                     DWORD from       = (UBYTE*)lbuf - zmsdata->linebuf;
  673.                     DWORD to         = (UBYTE*)lbuf - zmsdata->linebuf + (pbuflen - (lbuf - lbuf_ ));
  674.                     DWORD copyfrom   = (UBYTE*)lbuf_ - zmsdata->linebuf;
  675.  
  676.                     zmsdata->linebuf = erealloc(zmsdata->linebuf,
  677.                         strlen(zmsdata->linebuf) - (lbuf - lbuf_) + pbuflen + 1,"linebuf");
  678.                     memmove(zmsdata->linebuf + to,
  679.                             zmsdata->linebuf + from,
  680.                             transbytes);
  681.                     memcpy(copyfrom + zmsdata->linebuf,pbuf,pbuflen);
  682.  
  683.                     lbuf = zmsdata->linebuf + to;
  684.  
  685.                 }
  686. /*
  687. fprintf(stderr,"置換後(%c%c%c):%s\n",*lbuf,*(lbuf+1),*(lbuf+2),zmsdata->linebuf);
  688. */
  689. /*
  690.                 lbuf += pbuflen;
  691. */
  692.                 efree(pbuf,"pbuf");
  693.             } else {            /* マクロと一致せず: 一文字ずらす */
  694.                 lbuf++;
  695.             }
  696.         }
  697.         mbuf = mbuf->next;
  698.     }
  699. }
  700.  
  701. /* 文字列対応パラメータ取得 */
  702. UBYTE *getpara2(UBYTE *lbuf, char **para)
  703. {
  704.     UBYTE *lbuf_;
  705.     DWORD plen;
  706.  
  707.     lbuf_ = lbuf = skipSpc2(lbuf);
  708.     while (*lbuf != ','  && *lbuf != ' '  &&
  709.            *lbuf != '\t' && *lbuf != 0xFF &&
  710.            *lbuf != 0x0d && *lbuf != 0x0a && *lbuf != '/') {
  711.         lbuf++;
  712.     }
  713.  
  714.     plen = lbuf - lbuf_;
  715.     *para = (UBYTE*)emalloc(sizeof(UBYTE) * (plen + 1),"para");
  716.     strncpy(*para,lbuf_,plen);
  717.     (*para)[plen] = '\0';
  718.  
  719.     return lbuf;
  720. }
  721.